-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Add LiteDB.Spatial #2708
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Add LiteDB.Spatial #2708
Conversation
- Implemented GeoBoundingBox for spatial bounding box calculations. - Added GeoJson for serialization and deserialization of GeoShape objects. - Introduced GeoMath for geographical calculations including distance metrics. - Created GeoShape as an abstract base class with derived types: GeoPoint, GeoLineString, and GeoPolygon. - Added GeoValidation for coordinate validation. - Developed Geometry utility class for geometric operations like point containment and intersection checks. - Implemented LongitudeRange for handling longitude ranges with wrapping. - Created Spatial class for spatial indexing and querying capabilities. - Added SpatialIndexing for Morton code computation for spatial indexing. - Introduced SpatialOptions for configuration of spatial operations.
…ial-patch1-and-spatial-patch3 Add tolerance-aware spatial helpers and expressions
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting
LiteDB/Spatial/GeoMath.cs
Outdated
| internal static GeoBoundingBox BoundingBoxForCircle(GeoPoint center, double radiusMeters) | ||
| { | ||
| if (center == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(center)); | ||
| } | ||
|
|
||
| if (radiusMeters < 0d) | ||
| { | ||
| throw new ArgumentOutOfRangeException(nameof(radiusMeters)); | ||
| } | ||
|
|
||
| var angularDistance = radiusMeters / EarthRadiusMeters; | ||
|
|
||
| var minLat = ClampLatitude(center.Lat - angularDistance / DegToRad); | ||
| var maxLat = ClampLatitude(center.Lat + angularDistance / DegToRad); | ||
|
|
||
| var minLon = NormalizeLongitude(center.Lon - angularDistance / DegToRad); | ||
| var maxLon = NormalizeLongitude(center.Lon + angularDistance / DegToRad); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compute lon span for near queries using latitude
The circle bounding box helper uses the same angular distance for latitude and longitude (GeoMath.BoundingBoxForCircle). Longitudinal distance shrinks with cos(latitude), so near the poles the computed minLon/maxLon will be far too narrow. Spatial.Near relies on this box both for index range construction and to pre‑filter candidates (queryBoundingBox.Contains(point)), so points that are actually within radiusMeters but lie just east/west of the center at high latitudes will be skipped before distance is checked, yielding false negatives. The longitude delta should be divided by Math.Cos(center.Lat) (with a clamp around the poles) before converting back to degrees.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compute lon span for near queries using latitude
The circle bounding box helper uses the same angular distance for latitude and longitude (
GeoMath.BoundingBoxForCircle). Longitudinal distance shrinks withcos(latitude), so near the poles the computedminLon/maxLonwill be far too narrow.Spatial.Nearrelies on this box both for index range construction and to pre‑filter candidates (queryBoundingBox.Contains(point)), so points that are actually withinradiusMetersbut lie just east/west of the center at high latitudes will be skipped before distance is checked, yielding false negatives. The longitude delta should be divided byMath.Cos(center.Lat)(with a clamp around the poles) before converting back to degrees.Useful? React with 👍 / 👎.
@codex please fix the problem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary
- Adjusted the circle bounding box calculation to scale longitude span by the cosine of the center latitude and clamp the range near the poles, preventing high-latitude near queries from excluding valid points. LiteDB/Spatial/GeoMath.csL115-L138
Testing
⚠️ not run (not requested)
* Add GeographicLib polar regression tests * Merged regressions * Improve spatial accuracy near poles (#47)
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting
| [typeof(Regex)] = new RegexResolver(), | ||
| [typeof(ObjectId)] = new ObjectIdResolver(), | ||
| [typeof(String)] = new StringResolver(), | ||
| [typeof(Nullable)] = new NullableResolver() | ||
| [typeof(Nullable)] = new NullableResolver(), | ||
| [typeof(LiteDB.Spatial.Spatial)] = new SpatialResolver() | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add resolver for SpatialExpressions LINQ methods
The new SpatialResolver handles both Spatial and SpatialExpressions methods, but the resolver table only registers typeof(LiteDB.Spatial.Spatial). Calls written as SpatialExpressions.Near/Within/Intersects in LINQ will therefore hit the VisitMethodCall path with no resolver, where ParameterExpressionVisitor.Test will see a query parameter and the visitor throws NotSupportedException. Users who import LiteDB and use the SpatialExpressions helpers directly—rather than the Spatial API—will not be able to translate these queries. The resolver table should also register typeof(LiteDB.SpatialExpressions) so both entry points work as intended.
Useful? React with 👍 / 👎.
This pull request introduces comprehensive support for spatial queries in LiteDB, including new spatial query methods, LINQ integration, and corresponding tests and benchmarks. The changes add spatial document models and generators for benchmarks, implement spatial query translation in the LINQ provider, define new BSON expression methods for spatial operations, and ensure spatial predicates are optimized during query planning.
Key changes include:
Spatial Query Support and Integration:
SpatialQueryBenchmarksclass with multiple spatial query benchmarks (near, bounding box, polygon containment, route intersection) using new spatial document models and data generators. (SpatialQueryBenchmarks.cs,SpatialDocument.cs,SpatialDocumentGenerator.cs) [1] [2] [3]SpatialResolverto map spatial method calls in LINQ queries to corresponding database expressions, enabling LINQ queries to use spatial operators. (SpatialResolver.cs,LinqExpressionVisitor.cs) [1] [2]Spatial Expression Methods:
SPATIAL_NEAR,SPATIAL_WITHIN,SPATIAL_INTERSECTS,SPATIAL_CONTAINS_POINT, and bounding box intersection. These methods handle conversion from BSON to spatial types and call the appropriate spatial logic. (Document/Expression/Methods/Spatial.cs)Query Optimization:
QueryOptimization.cs) [1] [2]Testing:
SpatialTests.cs)